#
# Rules for building a library target
#
# The following variables must be passed when calling this file:
#
#   BASE_DIR         - base directory of the build system
#   REPOSITORIES     - repositories providing libs and headers
#   VERBOSE          - build verboseness modifier
#   VERBOSE_DIR      - verboseness modifier for changing directories
#   VERBOSE_MK       - verboseness of make calls
#   BUILD_BASE_DIR   - base of build directory tree
#   LIB_CACHE_DIR    - library build cache location
#   LIB_PROGRESS_LOG - library build log file
#

#
# Function that searches for files in all
# repositories and returns the first match.
#
select_from_repositories = $(firstword $(foreach REP,$(REPOSITORIES),$(wildcard $(REP)/$(1))))

#
# Read SPECS configuration
#
-include $(call select_from_repositories,etc/specs.conf)
-include $(BUILD_BASE_DIR)/etc/specs.conf

#
# The target name corresponds to the basename of the .lib.a file
#
TARGET = $(subst .lib.a,,$(notdir $(LIB_O_TARGET)))

#
# Prefix all object files with the library name
#
OBJ_PREFIX = $(TARGET)_

#
# Include specifics, for example platform, kernel-api etc.
#
include $(foreach SPEC,$(SPECS),$(call select_from_repositories,mk/spec-$(SPEC).mk))

#
# Search source repositories for matching libname.mk file
#
# First, we determine all possible locations where the libname.mk
# file could reside. These locations depend on the repositories and
# the SPECS.
#
LIB_MK_DIRS = $(foreach REP,$(REPOSITORIES),$(REP)/lib/mk $(addprefix $(REP)/lib/mk/,$(SPECS)))

#
# Of all possible file locations, use the (first) one that actually exist.
#
LIB_MK_FILE = $(firstword $(wildcard $(addsuffix /$(TARGET).mk,$(LIB_MK_DIRS))))

#
# Sanity check to detect missing library description file
#
ifeq ($(LIB_MK_FILE),)
done:
	@echo "Skip $(TARGET) library because of missing library description file $(TARGET).mk"
endif

#
# Determine the repository base directory from the absolute pathname
# of the choosen libname.mk file. We need to specify the override
# command because REP_DIR was first set by prg.mk when building a
# program target. The repository of a library could be a different
# one.
#
# Finally, we strip the trailing slash from the path. The slash was
# used to match the whole directory in 'findstring'.
#
override REP_DIR := $(firstword $(foreach REP,$(REPOSITORIES),$(findstring $(REP)/,$(LIB_MK_FILE))))
override REP_DIR := $(REP_DIR:/=)

#
# Prevent <libname>.mk rules to be executed as default rule
#
all::

#
# Include library build instructions
#
BACKUP_INC_DIR := $(INC_DIR)
include $(LIB_MK_FILE)

#
# Sanity check for INC_DIR overrides
#
ifneq ($(filter-out $(INC_DIR),$(BACKUP_INC_DIR)),)
all::
	@$(ECHO) "Error: $(LIB_MK_FILE) overrides INC_DIR instead of appending" ; false
endif

#
# Check if the requirements of the target are satisfied
#
UNSATISFIED_REQUIREMENTS = $(filter-out $(SPECS),$(REQUIRES))
ifneq ($(UNSATISFIED_REQUIREMENTS),)
all::
	@$(ECHO) "Error: Library $(TARGET) requires $(DARK_COL)$(UNSATISFIED_REQUIREMENTS)$(DEFAULT_COL)" ; false
endif

#
# Include lib-import descriptions of all used libraries and the target library
#
include $(foreach LIB,$(LIBS),$(call select_from_repositories,lib/import/import-$(LIB).mk))

#
# Include global definitions
#
include $(BASE_DIR)/mk/global.mk

#
# Build the libraries we depend on
#
ifneq ($(LIBS),)
all::
	$(VERBOSE_MK)$(MAKE) $(VERBOSE_DIR)  -f $(BASE_DIR)/mk/build_libs.mk \
	  BASE_DIR=$(BASE_DIR) \
	  BUILD_BASE_DIR=$(BUILD_BASE_DIR) \
	  TARGET_DIR=$(TARGET_DIR) \
	  REPOSITORIES="$(REPOSITORIES)" \
	  VERBOSE=$(VERBOSE) \
	  VERBOSE_DIR=$(VERBOSE_DIR) \
	  VERBOSE_MK=$(VERBOSE_MK) \
	  LIB_CACHE_DIR=$(LIB_CACHE_DIR) \
	  LIB_PROGRESS_LOG=$(LIB_PROGRESS_LOG) \
	  $(addsuffix .lib.a,$(LIBS))
endif

#
# Name of <libname>.lib.a file to create
#
LIBOBJ = $(addsuffix .lib.a,$(TARGET))

#
# Build <libname>.lib.a target only if it is
# not already contained in the library build log
#
include $(LIB_PROGRESS_LOG)
ifeq ($(filter $(LIBOBJ),$(LIBS_READY)),)

#
# Print message for the currently built library
#
all::
	$(MSG_LIB)$(TARGET)

#
# Create <libname>.lib.a file.
#
all:: $(LIBOBJ)

include $(BASE_DIR)/mk/generic.mk

#
# Rule to build the <libname>.lib.a file
#
$(LIBOBJ):: $(OBJECTS)
	$(MSG_MERGE)$(LIBOBJ)
	$(VERBOSE)$(AR) -rc $@ $^

endif

#
# Include built library in library build log
# If library is already contained in the log,
# do something (true) to avoid a message by
# make.
#
all::
ifeq ($(filter $(LIBOBJ),$(LIBS_READY)),)
	@echo "LIBS_READY += $(LIBOBJ)" >> $(LIB_PROGRESS_LOG)
else
	@true
endif
